package eu.codlab.mouse_client;

import java.io.IOException;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;

public class GoActivity extends Activity {
	private MouseFragment m;
	private MainFragment main;
	private NfcAdapter _nfc;
	private boolean _write_mode;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		main = null;
		m = null;

		_nfc = NfcAdapter.getDefaultAdapter(this);
		_write_mode = false;
	}

	public void enableWriteMode() {
		displayMessage(R.string.nfcwaiting);
		_write_mode = true;
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
		IntentFilter[] filters = new IntentFilter[] { tagDetected };
		_nfc.enableForegroundDispatch(this, pendingIntent, filters, null);
	}

	@Override
	public void onNewIntent(Intent intent) {
		if(_write_mode) {
			_write_mode = false;
			Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
			writeTag(tag);
		}else{
			setIntent(intent);
		}
	}
	
	private String getUrl(){
		SharedPreferences p = getSharedPreferences("MOUSE_PREFS", 0);
		String server = p.getString("ip","");
		String ip = p.getString("port","");
		
		return "http://codlab.eu/mouse?s="+server+"&i="+ip;
	}
	
	//extracted from here
	//http://www.netmagazine.com/tutorials/getting-started-nfc-android
	private boolean writeTag(Tag tag) {
		//NdefRecord appRecord = NdefRecord.createApplicationRecord("eu.codlab.mouse_client");
		NdefRecord cardRecord = NdefRecord.createUri(getUrl());
		//new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, , new byte[0], payload);
		NdefMessage message = new NdefMessage(new NdefRecord[] { cardRecord}); //cardRecord, 
		try {
			// see if tag is already NDEF formatted
			Ndef ndef = Ndef.get(tag);
			if (ndef != null) {
				ndef.connect();
				if (!ndef.isWritable()) {
					displayMessage(R.string.nfcreadonly);
					return false;
				}
				// work out how much space we need for the data
				int size = message.toByteArray().length;
				if (ndef.getMaxSize() < size) {
					displayMessage(R.string.nfcspaceprob);
					return false;
				}
				ndef.writeNdefMessage(message);
				displayMessage(R.string.nfcsuccess);
				return true;
			} else {
				// attempt to format tag
				NdefFormatable format = NdefFormatable.get(tag);
				if (format != null) {
					try {
						format.connect();
						format.format(message);
						displayMessage(R.string.nfcsuccess);
						return true;
					} catch (IOException e) {
						displayMessage(R.string.nfcunablendef);
						return false;
					}
				} else {
					displayMessage(R.string.nfcnotndef);
					return false;
				}
			}
		} catch (Exception e) {
			displayMessage(R.string.nfcfailed);
		}
		return false;
	}

	public void displayMessage(final String msg){
		runOnUiThread(new Runnable(){
			public void run(){
				Toast.makeText(GoActivity.this, msg, Toast.LENGTH_LONG).show();
			}
		});
	}

	public void displayMessage(final int msg){
		runOnUiThread(new Runnable(){
			public void run(){
				Toast.makeText(GoActivity.this, msg, Toast.LENGTH_LONG).show();
			}
		});
	}

	@Override
	public void onStart(){

		super.onStart();
		if(findViewById( R.id.fragment ) != null && this.getFragmentManager().getBackStackEntryCount() == 0){
			FragmentTransaction xact = getFragmentManager().beginTransaction();
			main = new MainFragment();
			xact.add(R.id.fragment, main);
			xact.commit();
		}

	}
	
	@Override
	public void onResume(){
		Intent i = getIntent();
		if(i != null && i.getData() != null){
			killClient();
			displayMessage(i.getData().toString());
			Uri data = i.getData();
			String s = data.getQueryParameter("s");
			String ip = data.getQueryParameter("i");
			if(main != null){
				main.setServer(s, ip);
			}
			i.setData(null);
		}
		super.onResume();
	}

	public void destack(){
		m=null;
		main = null;
		while(findViewById( R.id.fragment ) != null && this.getFragmentManager().getBackStackEntryCount() != 0){
			this.getFragmentManager().popBackStackImmediate();
		}
	}

	public void go() {
		if(m == null){
			FragmentTransaction xact = this.getFragmentManager().beginTransaction();
			m = new MouseFragment();
			//xact.show(_extension);
			//xact.replace(R.id.extension_fragment, _extension, nom);
			xact.replace(R.id.fragment, m,"MOUSE");
			xact.addToBackStack(null);
			xact.commit();
		}
		getActionBar().setDisplayHomeAsUpEnabled(true);
	}
	@Override
	public void onSaveInstanceState(Bundle out){
		getActionBar().setDisplayHomeAsUpEnabled(false);
		try{
			getFragmentManager().putFragment(out, "MAIN", main);
		}catch(Exception e){
		}
		if(m != null){
			try{
				getFragmentManager().putFragment(out, "MOUSE", m);
			}catch(Exception e){
			}
		}
		m = null;
		main = null;
		super.onSaveInstanceState(out);
	}

	@Override
	public void onRestoreInstanceState(Bundle in){
		m = null;
		if(in != null){
			if(in.containsKey("MAIN")){
				if(main != null){
					popmain();
				}
				main = (MainFragment) getFragmentManager().getFragment(in, "MAIN");
			}
			if(in.containsKey("MOUSE")){
				m = (MouseFragment) getFragmentManager().getFragment(in, "MOUSE");
				go();
			}
		}

	}

	private void pop(){

		FragmentManager fm = getFragmentManager();
		FragmentTransaction xact = fm.beginTransaction();
		xact.remove(m);
		xact.commit();
		fm.popBackStackImmediate();
		m = null;
		getActionBar().setDisplayHomeAsUpEnabled(false);
	}


	private void popmain(){

		FragmentManager fm = getFragmentManager();
		FragmentTransaction xact = fm.beginTransaction();
		xact.remove(main);
		xact.commit();
		fm.popBackStackImmediate();
		main = null;
		getActionBar().setDisplayHomeAsUpEnabled(false);
	}

	@Override
	public void onBackPressed(){
		if(m != null){
			pop();
		}else
			super.onBackPressed();
	}
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case android.R.id.home:
			if(m != null){
				pop();
				return true;
			}
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	public void killClient(){
		Client c = new Client();
		c.destroy();
	}

	@Override
	public void onPause(){
		killClient();
		super.onPause();
	}

	@Override
	public void onDestroy(){
		killClient();
		super.onDestroy();
	}
}
